package nm.widgets.geom;

import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

public class ClockHand implements Shape {
	public static final int POINTS = 6;
	public static final int P1 = 0;
	public static final int P2 = 1;
	public static final int P3 = 2;
	public static final int P4 = 3;
	public static final int P5 = 4;
	public static final int P6 = 5;
	
	public ClockHand(Point2D c, int marks, int stroke, int radius, int time) {
		this.cx = (int)c.getX();
		this.cy = (int)c.getY();
		this.marks = marks;
		this.xpoints = new int[POINTS];
		this.ypoints = new int[POINTS];
		setTime(time);
		setRadius(radius);
		setStrokeSize(stroke);
		
		getPoints(POINTS, marks, stroke, cx, cy, radius, time);
		this.hand = new Polygon(xpoints, ypoints, POINTS);
	}
	
	public void getPoints(int npoints, int marks, double stroke, int cx, int cy, 
			int radius, int time) {
		
		double tleft = (2 * Math.PI * time) / marks - Math.PI;
		double tright = (2 * Math.PI * time) / marks;
		double tmiddle = (2 * Math.PI * time) / marks - (Math.PI / 2);
		
		double r = radius;
		double r1 = stroke / 2.0;
		double r2 = radius - (radius / 10.0);
		
		xpoints[P3] = getXPoint(cx, r, tmiddle);
		ypoints[P3] = getYPoint(cy, r, tmiddle);

		xpoints[P1] = getXPoint(cx, r1, tleft);
		ypoints[P1] = getYPoint(cy, r1, tleft);
		
		xpoints[P5] = getXPoint(cx, r1, tright);
		ypoints[P5] = getYPoint(cy, r1, tright);

		xpoints[P2] = getXPoint(xpoints[P1], r2, tmiddle);
		ypoints[P2] = getYPoint(ypoints[P1], r2, tmiddle);

		xpoints[P4] = getXPoint(xpoints[P5], r2, tmiddle);
		ypoints[P4] = getYPoint(ypoints[P5], r2, tmiddle);
		
		xpoints[P6] = xpoints[P1];
		ypoints[P6] = ypoints[P1];
	}
	
	public int getXPoint(double x, double r, double theta) {
		return (int)(x + r * Math.cos(theta));
	}
	
	public int getYPoint(double y, double r, double theta) {
		return (int)(y + r * Math.sin(theta));
	}
	
	public void setTime(int time) {
		this.time = time;
	}
	
	public void setRadius(int radius) {
		this.radius = radius;
		this.getPoints(POINTS, marks, stroke, cx, cy, radius, time);
		this.hand = new Polygon(xpoints, ypoints, POINTS);
	}
	
	public void setStrokeSize(int stroke) {
		this.stroke = stroke;
		this.getPoints(POINTS, marks, stroke, cx, cy, radius, time);
	}
	
	public void move(int time) {
		setTime(time);
		this.getPoints(POINTS, marks, stroke, cx, cy, radius, time);
		this.hand = new Polygon(xpoints, ypoints, POINTS);
	}
	
	
	// Shape implementation
	public boolean contains(double arg0, double arg1, double arg2, double arg3) {
		return hand.contains(arg0, arg1, arg2, arg3);
	}
	public boolean contains(double arg0, double arg1) {
		return hand.contains(arg0, arg1);
	}
	public boolean contains(Point2D arg0) {
		return hand.contains(arg0);
	}
	public boolean contains(Rectangle2D arg0) {
		return hand.contains(arg0);
	}
	public Rectangle getBounds() {
		return hand.getBounds();
	}
	public Rectangle2D getBounds2D() {
		return hand.getBounds2D();
	}
	public PathIterator getPathIterator(AffineTransform arg0, double arg1) {
		return hand.getPathIterator(arg0, arg1);
	}
	public PathIterator getPathIterator(AffineTransform arg0) {
		return hand.getPathIterator(arg0);
	}
	public boolean intersects(double arg0, double arg1, double arg2, double arg3) {
		return hand.intersects(arg0, arg1, arg2, arg3);
	}
	public boolean intersects(Rectangle2D arg0) {
		return hand.intersects(arg0);
	}

	//instance variables
	private int cx, cy, stroke, marks, radius, time;
	private int[] xpoints, ypoints;
	private Polygon hand;
	
//	public static void main(String[] args) throws Exception {
//		javax.swing.JFrame f = new javax.swing.JFrame();
//		f.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
//		f.setSize(400, 400);
//		
//		int cx = 200;
//		int cy = 200;
//		int marks = 60;
//		int stroke = 4;
//		int radius = 100;
//		int time = 15;
//
//		ClockHand hand = new ClockHand(cx, cy, marks, stroke, radius, time, Color.BLACK);
//		f.add(hand);
//		f.setVisible(true);
//
//		for(int c = 0; ; c++) {
//			hand.move(c);
//			Thread.sleep(100);
//		}
//	}
	
}//end ClockHand
